﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public class RegionObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RegionObject"/> class.
        /// </summary>
        public RegionObject()
        {
        }
    }

    /// <summary>
    /// This specifies a region growing filter. Another alternative might be the
    /// "FloodFill" filter
    /// </summary>
    public class RegionGrowing : BaseImageFilter
    {
        List<Point> m_aSeed = new List<Point>();
        Point[] m_aFilter = new Point[8];

        /// <summary>
        /// Default constructor, specifying a set of seeds
        /// </summary>
        public RegionGrowing()
        {
            m_aFilter = new Point[]{
                new Point(0,1), 
                new Point(1,0), 
                new Point(-1,0), 
                new Point(0,-1)
            };
        }

        /// <summary>
        /// Use this to create a clone of this filter
        /// </summary>
        /// <param name="_regionGrowing"></param>
        internal RegionGrowing(RegionGrowing _regionGrowing)
        {
            this.m_aFilter = _regionGrowing.m_aFilter;
            this.m_aSeed = _regionGrowing.m_aSeed;
        }

        /// <summary>
        /// Execute this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;
            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;

            int nOddOrEven = 0;
            int i = 0;

            Color color = Color.Transparent;
            Color colorTemp = Color.Transparent;
            int nX = 0;
            int nY = 0;
            for (i = 0; i < m_aFilter.Length; i++)
            {
                nOddOrEven = i % 2;
                Random random = new Random(DateTime.Now.Millisecond);

                int y = 0;
                int x = 0;
                for (y = 0; y < nHeight; y += 2)
                {
                    for (x = 0; x < nWidth; x += 2)
                    {
                        nX = x + m_aFilter[i].X;
                        nY = y + m_aFilter[i].Y;
                        if (nX < 0) nX = 0;
                        if (nY < 0) nY = 0;
                        if (nX > bitmap.Width - 1) nX = bitmap.Width - 1;
                        if (nY > bitmap.Height - 1) nY = bitmap.Height - 1;
                        m_aSeed.Add(new Point(nX,nY));
                    }
                }

                for (int j = 0; j < m_aSeed.Count; j++)
                {
                    nX = m_aSeed[j].X;
                    nY = m_aSeed[j].Y;
                    color = bitmap.GetPixel(nX, nY);
                    foreach (Point pt in m_aFilter)
                    {
                        int nXTemp = nX + pt.X;
                        int nYTemp = nY + pt.Y;
                        if (BoundLimitsReached(bitmap, nXTemp, nYTemp)) continue;
                        colorTemp = bitmap.GetPixel(nXTemp, nYTemp);
                        if (!ColorFunctions.IsInLuminanceTolerance(color,colorTemp,0.5f))
                        {
                            bitmap.SetPixel(nXTemp, nYTemp, color);
                        }
                    }
                }
            }
            return _bitmap;
        }


        //public void GrowRegion(int nStart, int nEnd, UnsafeBitmap bitmap, Direction direction, Point pt)
        //{
        //    Color color = Color.FromArgb(50,50,50);
        //    List<Point> aPoint = new List<Point>();
        //    int nCount = 0;
        //    int nX = pt.X;
        //    int nY = pt.Y;
        //    int nLength = 0;
        //    bool bResult = false;
        //    List<Color> aColor = new List<Color>();

        //    Color colorCurrent = bitmap.GetPixel(nX, nY);
        //    aColor.Add(colorCurrent);
        //    nCount = 1;
        //    for (nLength = nStart; nLength < nEnd; nLength++)
        //    {
        //        for (int nDir = 0; nDir < 2; nDir++)
        //        {
        //            for (int nWalk = 1; nWalk <= nLength; nWalk++)
        //            {
        //                nX = nX + 1 * direction.CurrentDirection.Width;
        //                nY = nY + 1 * direction.CurrentDirection.Height;
        //                //Debug.WriteLine(string.Format("NX: {0}, NY: {1}",nX.ToString(), nY.ToString()));
        //                if (BoundLimitsReached(bitmap, nX, nY))
        //                {
        //                    return;
        //                }
        //                Color colorPrev = bitmap.GetPixel(nX, nY);

        //                if (colorPrev.R>colorCurrent.R && colorPrev.G>colorCurrent.G && colorPrev.B>colorCurrent.B)
        //                bitmap.SetPixel(nX, nY, colorCurrent);
        //                nCount++;
        //            }
        //            direction.CycleDir();
        //        }
        //    }
        //}

        /// <summary>
        /// Determine whether we've reached the extent
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="nX"></param>
        /// <param name="nY"></param>
        /// <returns></returns>
        public bool BoundLimitsReached(UnsafeBitmap bitmap, int nX, int nY)
        {
            return (nX < 0 || nX > bitmap.Width - 1 || nY < 0 || nY > bitmap.Height - 1);
        }

        /// <summary>
        /// Use this to create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new RegionGrowing(this);
        }
    }
}
